
import os
from selenium import webdriver
from pykeyboard import PyKeyboard
from pymouse import PyMouse

class KWDriven:

    driver = None

    def get_driver(self, browser):
        """
        通过单例模式，应用反射机制，得到指定浏览器驱动对象
        :param browser:浏览器名称（字符串）
        :return:浏览器驱动对象
        """
        if self.driver is None:
            if hasattr(webdriver, browser):
                self.driver = getattr(webdriver, browser)()
                self.driver.implicitly_wait(10)
                self.driver.maximize_window()
            else:
                print('浏览器名称错误')
        return self.driver

    def open_page(self, url):
        """
        打开一个指定的页面
        :param url: 浏览器页面地址
        :return:None
        """
        self.driver.get(url)

    def input(self, attr, value):
        """
        向一个文本框输入内容，页面元素定位采用css_selector
        :param attr:指定元素的css属性值
        :param value:要输入的值
        :return:None
        """
        element = self.driver.find_element_by_css_selector(attr)
        element.click()
        element.clear()
        element.send_keys(value)

    def input_random(self, attr, min, max):
        import random
        random_number = random.randint(int(min),int(max))
        element = self.driver.find_element_by_css_selector(attr)
        element.click()
        element.clear()
        element.send_keys(str(random_number))

    def click(self, attr):
        """
        单击页面上的指定元素
        :param attr: 指定元素的css属性值
        :return: None
        """
        self.driver.find_element_by_css_selector(attr).click()

    def select_random_option(self, attr):
        """
        随机选择除了第一项之外的任意项（option）
        :param attr: select元素的css属性值
        :return: None
        """
        select_element = self.driver.find_element_by_css_selector(attr)  # 获取select元素对象
        from selenium.webdriver.support.select import Select
        select_options = len(Select(select_element).options)  # 获取select下option的数量
        import random
        random_index = random.randint(1,select_options-1)  # 获取除了第0项外的随机下标
        Select(select_element).select_by_index(random_index)

    def assert_contain(self, attr, expect):
        content = self.driver.find_element_by_css_selector(attr).text
        if expect in  content:
            print('test pass')
        else:
            print('test fail')

    def assert_equal(self, expect, actual):
        if expect == actual:
            print('test pass')
        else:
            print('test fail')

    def assert_not_exist(self, attr):
        try:
            self.driver.find_element_by_css_selector(attr)
            print('test fail')
        except Exception  as e:
            print('test pass')

    def sleep(self, second):
        import time
        time.sleep(int(second))

    def close(self):
        self.driver.quit()
        self.driver = None

    mouse = PyMouse()
    keyboard = PyKeyboard()

    @classmethod
    def match_img(cls, target):
        """
        图像匹配，大图和小图通过opencv库进行对比，返回坐标
        :param target: 图片文件的名称
        :return:在大图上的坐标
        """
        image_path = ".\\images"
        template_path = os.path.join(image_path, target)
        screen_path = os.path.join(image_path, 'screen.png')
        from PIL import ImageGrab
        ImageGrab.grab().save(screen_path)
        import cv2
        # 读取大图
        screen = cv2.imread(screen_path)
        # 读取小图
        template = cv2.imread(template_path)
        # 调用匹配算法
        result = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED)

        min, max, min_loc, max_loc = cv2.minMaxLoc(result)

        # 计算矩形十字中心点的坐标
        x = max_loc[0] + int(template.shape[1] / 2)
        y = max_loc[1] + int(template.shape[0] / 2)

        # 如果没匹配成功，则返回的是-1，-1
        return x, y

    @classmethod
    def click_image(cls, target):
        """
        对通过图像识别的元素执行单击操作
        :param target: 小图文件的名称
        :return: None
        """
        x, y = cls.match_img(target)
        if x == -1 and y == -1:
            return
        cls.mouse.click(x, y)

    # 双击图片元素
    @classmethod
    def double_click_image(cls, target):
        """
        对通过图像识别的元素执行双击操作
        :param target: 小图文件的名称
        :return: None
        """
        x, y = cls.match_img(target)
        if x == -1 and y == -1:
            return
        cls.mouse.click(x, y, n=2)

    # 向一个文本框图片输入
    @classmethod
    def input_image(cls, target, value):
        """
        对通过图像识别的元素执行输入操作
        :param target: 小图文件的名称
        :param value: 小图文件的名称
        :return: None
        """
        x, y = cls.match_img(target)
        if x == -1 and y == -1:
            return
        cls.keyboard.type_string(value)

if __name__ == '__main__':
    kwd = KWDriven()
    kwd.get_driver('Firefox')
    kwd.open_page('http://192.168.221.128:8080/WoniuBoss4.0/')
    kwd.input('div.row:nth-child(1) > input:nth-child(1)', 'WNXA008')
    kwd.input('div.row:nth-child(2) > input:nth-child(1)', 'Woniu12345')
    kwd.input('input.col-md-6', '0000')
    kwd.click('.btn')
    kwd.sleep('3')
    kwd.assert_contain('.welcome', '闫少华')
    kwd.open_page('http://192.168.221.128:8080/WoniuBoss4.0/assets')
    kwd.click('button.btn-padding:nth-child(1)')
    kwd.sleep('2')
    kwd.select_random_option('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > select:nth-child(2)')
    kwd.select_random_option('select.form-control:nth-child(1)')
    # kwd.input('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(1) > input:nth-child(2)', '12345678901')
    kwd.input_random('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(1) > input:nth-child(2)','10000000000','99999999999')
    kwd.input('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(2) > input:nth-child(2)', '100')
    kwd.input('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > div:nth-child(1) > input:nth-child(2)', '闫少华')
    kwd.click('#addAss-form > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > div:nth-child(2) > input:nth-child(2)')
    kwd.click('div.datetimepicker:nth-child(21) > div:nth-child(3) > table:nth-child(1) > tfoot:nth-child(3) > tr:nth-child(1) > th:nth-child(1)')
    kwd.click('#addAss > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > button:nth-child(1)')
    kwd.sleep('2')
    kwd.assert_not_exist('.bootbox > div:nth-child(1) > div:nth-child(1) > div:nth-child(3) > button:nth-child(1)')
    kwd.close()
